package com.lucky.carcodepro.common;

import cn.hutool.core.util.ObjUtil;
import com.lucky.carcodepro.domain.bo.CurrentContextBo;

import java.util.Optional;

/**
 * 当前上下文持有者
 * 持有当前线程的上下文信息
 */
public class CurrentContextHolder {
    // 默认渠道名称
    public final static String DEFAULT_CHANNEL = "Pro";
    // 当前线程上下文
    private static final InheritableThreadLocal<CurrentContextBo> contextHolder = new InheritableThreadLocal<>();

    public static CurrentContextBo get() {
        return contextHolder.get();
    }

    /**
     * 获取当前用户ID
     * 如果未登录，则返回-1
     *
     * @return 当前用户ID
     */
    public static Integer getUserId() {
        if (ifLogin()) {
            return contextHolder.get().getUser().getId();
        }
        return -1;
    }


    /**
     * 获取当前请求渠道
     *
     * @return 默认返回 Pro
     */
    public static String getChannel() {
        return Optional.ofNullable(contextHolder.get())
                .map(CurrentContextBo::getAllHeaders)
                .map(headers -> headers.get("channel"))
                .map(Object::toString)
                .orElse(DEFAULT_CHANNEL);
    }

    /**
     * 获取当前请求渠道
     *
     * @return 默认返回 1
     */
    public static Integer getPackageId() {
        return Optional.ofNullable(contextHolder.get())
                .map(currentContextBo -> {
                    // 如果用户已登录，优先从用户信息中获取 packageId
                    if (ObjUtil.isNotNull(currentContextBo.getUser())) {
                        return currentContextBo.getUser().getPackageId();
                    }
                    // 用户未登录时，从请求头中获取 packageId
                    return Optional.ofNullable(currentContextBo.getAllHeaders().get("packageId"))
                            .map(Object::toString)
                            .map(Integer::parseInt)
                            .orElse(1);// 没有 packageId 时返回默认值 1
                })
                .orElse(1);// 如果 上下文为空，返回默认值 1
    }

    public static boolean ifLogin() {
        return ObjUtil.isNotNull(contextHolder.get()) && ObjUtil.isNotNull(contextHolder.get().getUser());
    }

    public static void set(CurrentContextBo bo) {
        contextHolder.set(bo);
    }

    /**
     * 避免内存泄露
     */
    public static void clear() {
        contextHolder.remove();
    }
}
